package org.openspaces.example.helloworld.processor;

import java.awt.Point;

import org.openspaces.core.GigaSpace;
import org.openspaces.core.GigaSpaceConfigurer;
import org.openspaces.core.space.UrlSpaceConfigurer;
import org.openspaces.events.EventDriven;
import org.openspaces.events.EventTemplate;
import org.openspaces.events.adapter.SpaceDataEvent;
import org.openspaces.events.notify.Notify;
import org.openspaces.example.helloworld.common.Direction;
import org.openspaces.example.helloworld.common.Roxel;
import org.openspaces.example.helloworld.common.StructureTuple;

import com.j_spaces.core.IJSpace;

@EventDriven @Notify
public class TrafficListener {

	 @EventTemplate
	    Roxel undecidedXRoads() {
	        Roxel template = new Roxel();
	        template.setId(null);
	        template.setOccupied(false);
	        template.setNorth(false);
	        template.setSouth(false);
	        template.setEast(false);
	        template.setWest(false);
	        return template;
	    }
	    
	    @SpaceDataEvent
	    public Roxel eventListener(Roxel roxel) {
	    
	    	  // connect to the space using its URL
	    	  IJSpace space = new UrlSpaceConfigurer("jini://*/*/processorSpace").space();
	    	  // use gigaspace wrapper to for simpler API
	    	   GigaSpace gigaSpace = new GigaSpaceConfigurer(space).gigaSpace();
	    	 
	
	    	gigaSpace.take(roxel);
	
	    	   
    	   Roxel template = new Roxel();
    	   template.setId(null);
    	   template.setX(roxel.getX());
    	   template.setY(roxel.getY());
    	   template.setTileCoords(roxel.getTileCoords());
    	   System.out.println("ausgangsroxel: " + roxel); 
		    	   
		    Roxel tmp = gigaSpace.take(template);
	    	System.out.println("ausm space genommen	: " + tmp);
		    
	
	    	
	    	
	    	int xTile = roxel.getTileCoords().x;
	    	int yTile = roxel.getTileCoords().y;
	    	int xRoxel = roxel.getX();
	    	int yRoxel = roxel.getY();
	    	StructureTuple struc = new StructureTuple();
	    	struc.setProcessed(true);
	    	struc = gigaSpace.read(struc);
	    	
	    	template = new Roxel();
	    	template.setId(null);
	        template.setTileCoords(new Point(xTile, yTile));
	        int occWest = struc.getBlockLen()/2;
	        int occNorth = struc.getBlockLen()/2;
	        
	    	for (int i=1; i<=struc.getBlockLen()/2; i++){
		        template.setX(xRoxel-i);
		        template.setY(yRoxel);
		        tmp = gigaSpace.read(template);
		        if(tmp!=null){
		        	if(!tmp.isOccupied()){
		        		occWest--;
		        	}
		        }
	    	}
	    	
	    	for (int i=1; i<=struc.getBlockLen()/2; i++){
		        template.setX(xRoxel);
		        template.setY(yRoxel-i);
		        tmp = gigaSpace.read(template);
		        if(tmp!=null){
		        	if(!tmp.isOccupied()){
		        		occNorth--;
		        	}
		        }
	    	}
	    	

	    	long tdiff = System.currentTimeMillis()-roxel.getLastSwitch();
	    	Direction lastDir = roxel.getLastDirection();
	    	Direction nextDir = Direction.TODECIDE;
	    	if(occNorth == 0 && occWest == 0){
	    		roxel.setSouth(true);
	    		roxel.setEast(true);
	    		nextDir = Direction.OPEN;
	    	}else if(occWest == 0 
	    			|| (occNorth > 0 && lastDir == Direction.EAST && tdiff >= 2000) 
	    			|| (occNorth > 0 && lastDir == Direction.SOUTH && tdiff < 2000) 
	    			|| (occNorth >= occWest && lastDir == Direction.OPEN )
	    			){
	    		roxel.setSouth(true);
	    		nextDir = Direction.SOUTH;
	    	}else{
	    		roxel.setEast(true);
	    		nextDir = Direction.EAST;
	    	}
	    	
	    	if(nextDir != lastDir){
	    		roxel.setLastSwitch(System.currentTimeMillis());
	    		roxel.setLastDirection(nextDir);
	    	}
	    	
	    	
	
	    	return roxel;
	    }
	}
